using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

using libsecondlife;

using Feathertail;
using Feathertail.Lua;



namespace NestBox
{
    class TeleportCmd : Feathertail.Command
    {
        private FeathertailClient _Client;

        private StringBuilder TeleportOutput;
        private ManualResetEvent TeleportComplete = new ManualResetEvent(false);

        private int TeleportTimeout = 30000;

        #region Callback Handlers
        void Self_OnTeleport(string message, MainAvatar.TeleportStatus status, MainAvatar.TeleportFlags flags)
        {
            switch (status)
            {
                case MainAvatar.TeleportStatus.Finished:
                    TeleportOutput.AppendLine("Teleport Completed");
                    _Client.Self.Status.Camera.CameraCenter = _Client.Self.Position;
                    TeleportComplete.Set();
                    break;

                case MainAvatar.TeleportStatus.Failed:
                    TeleportOutput.AppendLine("Teleport Failed: " + message);
                    TeleportComplete.Set();
                    break;

                default:
                    TeleportOutput.AppendLine("Teleport Update: " + message);
                    break;
            }

        }
        #endregion

        #region Command Members

        public void Setup(FeathertailClient Client)
        {
            _Client = Client;
            _Client.Self.OnTeleport += new MainAvatar.TeleportCallback(Self_OnTeleport);
        }

        [AttrLuaFunc("teleport", "Teleport to another region.","Target Region","x","y","z")]
        public string Teleport(string RegionName, float x, float y, float z)
        {
            TeleportOutput = new StringBuilder();

            if (RegionName == _Client.Network.CurrentSim.Name.ToLower())
            {
                TeleportOutput.AppendLine("TODO: Add the ability to teleport somewhere in the local region. " +
                    "Exiting for now, please specify a region other than the current one");
            }
            else
            {
                if (_Client.Grid.Regions.Count == 0)
                {
                    TeleportOutput.AppendLine("Caching estate sims...");
                    
                    _Client.Grid.RequestMapRegion(RegionName);
//                    _Client.Grid.RequestEstateSims(GridManager.MapLayerType.Objects);
//                    _Client.Grid.RequestEstateSims(GridManager.MapLayerType.Terrain);
                    System.Threading.Thread.Sleep(3000);
                }

                TeleportComplete.Reset();
                _Client.Self.Teleport(RegionName, new LLVector3(x, y, z));

                if (!TeleportComplete.WaitOne(TeleportTimeout, false))
                {
                    TeleportOutput.AppendLine("Teleport timed out after " + TeleportTimeout + " milliseconds.");
                }
            }
            return TeleportOutput.ToString();
        }

        public string HandleInput(string[] CmdLine)
        {
            TeleportOutput = new StringBuilder();

            if (CmdLine.Length < 5)
            {
                TeleportOutput.AppendLine("Usage: teleport [sim] [x] [y] [z]");
                TeleportOutput.AppendLine("Example: teleport hooper 182 40 26");
                return TeleportOutput.ToString();
            }

            string RegionName = CmdLine[1].ToLower();
            float x = float.Parse(CmdLine[2]);
            float y = float.Parse(CmdLine[3]);
            float z = float.Parse(CmdLine[4]);

            TeleportOutput.Append(Teleport(RegionName, x, y, z));
            return TeleportOutput.ToString();
        }

        public string[] GetCommandStrings()
        {
            return new string[] { "Teleport", "tp" };
        }

        public string GetSummaryText()
        {
            return "Telport to a given region and coords.";
        }

        public string GetHelpText()
        {
            return Environment.NewLine + "Usage: Teleport [region] [x] [y] [z]";
        }

        #endregion
    }
}
